home *** CD-ROM | disk | FTP | other *** search
- #
- # include <sccs.h>
-
- SCCSID(@(#)bndxsearch.c 8.1 12/31/84)
- /*
- ** BNDXSEARCH -- search an BTREE directory
- **
- ** Looks for an available page, if this would force out a page from
- ** the relation it adds its own. Searches each level of the dirctory
- ** for the lowest (highest) page on which the key could occur if mode
- ** is < (>) 0. At each level the number of keys on the page is checked
- ** if it is <= SEARCHFUDGE a linear sharch is done, otherwize a binary
- ** search is preformed. If the full key matches exactly the seach
- ** can stop. Note that the keys tell the minimum value on that page.
- **
- ** Parameters:
- ** d - pointer to descriptor of open relation
- ** tid - returns tid of page to start (end) looking
- ** key - to look for
- ** mode - < 0 lowkey, > 0 hikey
- ** keyok - true if all keys are assumed to be set
- ** path - if non-null, is set to the tids of the access path
- **
- ** Returns:
- ** -2 - pageflush failure
- ** -1 - get_page failure
- ** 0 - success
- **
- ** Side Effects:
- ** causes I/O
- **
- ** Requires:
- ** getpage, icompare, paramd, pageflush, top_acc, resetacc, etc.
- **
- ** Called By:
- ** find
- **
- ** History:
- ** Stolen from ndxsearch 7/26/80 (jiw)
- */
-
- # include <ingres.h>
- # include <aux.h>
- # include <symbol.h>
- # include <access.h>
- # include <lock.h>
-
- # define SEARCHFUDGE 6 /* # of linenos to do a binary search */
-
- bndxsearch(d, tidx, tuple, mode, keyok, path)
- struct descriptor *d;
- struct tup_id *tidx;
- char tuple[];
- int mode;
- int keyok;
- struct tup_id *path;
- {
- register struct tup_id *tid;
- register int i;
- long pageid;
- int j, keylen, dno, partialkey;
- char *p;
- int pagerr;
- struct accessparam relparm;
- int top;
- register bottom;
- extern char *get_addr();
-
- tid = tidx;
- pagerr = 0;
- paramd(d, &relparm); /* get domains in key order */
-
- /* assume fullkey is given */
- partialkey = FALSE;
-
- /* remove any key domains not given by the user */
- if (!keyok)
- {
- for (i = 0; dno = relparm.keydno[i]; i++)
- {
- if (d->relgiven[dno])
- continue;
- relparm.keydno[i] = 0;
- partialkey = TRUE;
- printf("partial key true\n");
- break;
- }
- }
-
- /* if the first key isn't given, just return else search directory */
- if (relparm.keydno[0] != 0)
- {
- /* The actual BTREE directory search must be performed */
- pageid = 0; /* BTREE root is page 0 */
- stuff_page(tid, &pageid);
-
- Acclock = FALSE;
-
- do
- {
- if (path)
- {
- bmove(tid, path++, sizeof(struct tup_id));
- }
-
- if (pagerr = get_page(d, tid))
- break; /* fatal error */
- Acc_head->bufstatus |= BUF_DIRECT; /* don't get confused */
- bottom = -1;
- top = Acc_head->nxtlino - 1;
- if (top >= SEARCHFUDGE) /* we are past breakeven */
- {
- printf("doing binary search\n");
- while (top != bottom) /* binary search */
- {
- tid->line_id = ((1 + top - bottom) >> 1) + bottom; /* get to half way point */
- p = get_addr(tid) + PGPTRSIZ;
- for (j = 0; dno = relparm.keydno[j]; j++)
- {
- keylen = d->relfrml[dno] & I1MASK;
- printf("data: ");
- printatt(d->relfrmt[dno], keylen, p);
- printf("| compared with: ");
- printatt(d->relfrmt[dno], keylen, &tuple[d->reloff[dno]]);
- printf("|\n");
- if (i = icompare(&tuple[d->reloff[dno]], p, d->relfrmt[dno], keylen))
- break;
- p += keylen;
- }
- /* if key is below directory, then we are in the bottom half */
- printf("i = %d, mode %d, partialkey %d, top %d, bottom %d\n", i, mode, partialkey, top, bottom);
- if (i < 0 || (i == 0 && partialkey && mode < 0))
- top = tid->line_id - 1;
-
- else if (i == 0 && !partialkey)
- {
- bottom = tid->line_id;
- break;
- }
- else
- bottom = tid->line_id;
- }
- }
- else /* do a linear search */
- {
- printf("doing linear search\n");
- for (tid->line_id = 0; (tid->line_id & I1MASK) < Acc_head->nxtlino; tid->line_id++)
- {
- printf("inside loop: tid\n");
- dumptid(tid);
- p = get_addr(tid) + PGPTRSIZ;
- for (i = 0; dno = relparm.keydno[i]; i++)
- {
- keylen = d->relfrml[dno] & I1MASK;
- printf("data: ");
- printatt(d->relfrmt[dno], keylen, p);
- printf("| compared with: ");
- printatt(d->relfrmt[dno], keylen, &tuple[d->reloff[dno]]);
- printf("|\n");
- if (j = icompare(&tuple[d->reloff[dno]], p, d->relfrmt[dno], keylen))
- break;
- printf("after break in tuple comp\n");
- p += keylen;
- }
- /* if key is below directory, then we have passed the position */
-
- printf("j = %d, mode %d, partialkey %d\n", j, mode, partialkey);
- if (j < 0)
- break;
-
- /* if lowkey search on partial key matches, then done */
- if (j == 0 && partialkey && mode < 0)
- break;
- if (j == 0 && mode < 0)
- {
- break;
- }
- }
- }
- if (bottom < 0)
- p = Acc_head->firstup;
- else
- {
- tid->line_id = bottom;
- p = get_addr(tid);
- }
- printf("result: ");
- dumptid(tid);
- bmove(p, tid, PGPTRSIZ);
- printf("and next tid: ");
- dumptid(tid);
- } while (Acc_head->mainpg); /* if at level zero then done */
- Acclock = TRUE;
-
- }
- tid->line_id = -1;
-
- if (path)
- {
- bmove(tid, path++, sizeof(struct tup_id));
- path->line_id = -2; /* impossible value */
- }
-
- printf("final: ");
- dumptid(tid);
- return (pagerr);
- }
-